import urllib.request
import urllib.error
import json
import os
from datetime import datetime
import random

# 简单的配置加载函数
def load_config():
    config = {
        'WEATHER_API_KEY': '',
        'WEATHER_API_BASE_URL': 'https://api.openweathermap.org/data/2.5',
        'SCHOOL_LAT': '39.9042',
        'SCHOOL_LON': '116.4074'
    }
    config_path = os.path.join(os.path.dirname(__file__), '..', 'config', '.env')
    if os.path.exists(config_path):
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                for line in f:
                    if '=' in line and not line.strip().startswith('#'):
                        key, value = line.strip().split('=', 1)
                        key = key.strip()
                        value = value.strip().strip('"\'')
                        if key in config:
                            config[key] = value
        except Exception:
            pass
    return config

# 加载配置
config = load_config()

class WeatherAPI:
    """
    天气API集成模块，用于获取实时天气数据和跑步适宜性评估
    支持OpenWeatherMap API，同时提供模拟数据功能
    """
    
    def __init__(self, api_key=None, base_url=None, lat=None, lon=None):
        self.api_key = api_key or config['WEATHER_API_KEY']
        self.base_url = base_url or config['WEATHER_API_BASE_URL']
        
        # 默认使用北京的坐标，实际使用时应从配置中获取
        self.lat = lat or config['SCHOOL_LAT']
        self.lon = lon or config['SCHOOL_LON']
        
        # 跑步适宜性参数配置
        self.optimal_temp_range = (10, 25)  # 最佳温度范围（摄氏度）
        self.max_wind_speed = 10  # 最大风速（m/s）
        self.max_rain_prob = 30  # 最大降雨概率（%）
        self.max_humidity = 80  # 最大湿度（%）
    
    def get_current_weather(self):
        """获取当前天气数据"""
        if not self.api_key:
            print("未配置天气API密钥，返回模拟数据")
            return self._get_mock_weather()
        
        try:
            url = f"{self.base_url}/weather"
            params = {
                'lat': self.lat,
                'lon': self.lon,
                'appid': self.api_key,
                'units': 'metric',  # 使用摄氏度
                'lang': 'zh_cn'  # 使用中文
            }
            
            # 构建查询字符串
            query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
            full_url = f"{url}?{query_string}"
            
            # 使用urllib获取数据
            with urllib.request.urlopen(full_url, timeout=10) as response:
                data = json.loads(response.read().decode('utf-8'))
                return self._parse_weather_data(data)
            
        except Exception as e:
            print(f"获取天气数据失败: {e}")
            return self._get_mock_weather()
    
    def get_weather_forecast(self, days=1):
        """获取天气预报数据"""
        if not self.api_key:
            print("未配置天气API密钥，返回模拟预报数据")
            return self._get_mock_forecast(days)
        
        try:
            url = f"{self.base_url}/forecast"
            params = {
                'lat': self.lat,
                'lon': self.lon,
                'appid': self.api_key,
                'units': 'metric',
                'lang': 'zh_cn',
                'cnt': days * 8  # 每3小时一个预报，一天8个
            }
            
            # 构建查询字符串
            query_string = '&'.join([f"{k}={v}" for k, v in params.items()])
            full_url = f"{url}?{query_string}"
            
            # 使用urllib获取数据
            with urllib.request.urlopen(full_url, timeout=10) as response:
                data = json.loads(response.read().decode('utf-8'))
                return self._parse_forecast_data(data, days)
            
        except Exception as e:
            print(f"获取天气预报失败: {e}")
            return self._get_mock_forecast(days)
    
    def _parse_weather_data(self, data):
        """解析天气API返回的数据"""
        return {
            'temperature': data.get('main', {}).get('temp', 0),
            'feels_like': data.get('main', {}).get('feels_like', 0),
            'humidity': data.get('main', {}).get('humidity', 0),
            'wind_speed': data.get('wind', {}).get('speed', 0),
            'weather': data.get('weather', [{}])[0].get('description', ''),
            'weather_icon': data.get('weather', [{}])[0].get('icon', ''),
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'rain': data.get('rain', {}).get('1h', 0),  # 最近1小时降雨量
            'is_raining': bool(data.get('rain', {}))
        }
    
    def _parse_forecast_data(self, data, days):
        """解析天气预报数据"""
        forecasts = []
        
        # 每天选择一个代表性的预报（例如中午12点）
        for i in range(days):
            # 简单起见，我们每隔8个预报（24小时）取一个
            index = min(i * 8, len(data.get('list', [])) - 1)
            forecast_item = data.get('list', [{}])[index]
            
            forecast = {
                'date': datetime.fromtimestamp(
                    forecast_item.get('dt', 0)).strftime('%Y-%m-%d'),
                'temperature': forecast_item.get('main', {}).get('temp', 0),
                'weather': forecast_item.get('weather', [{}])[0].get('description', ''),
                'humidity': forecast_item.get('main', {}).get('humidity', 0),
                'wind_speed': forecast_item.get('wind', {}).get('speed', 0),
                'rain_prob': forecast_item.get('pop', 0) * 100,  # 转换为百分比
            }
            forecasts.append(forecast)
        
        return forecasts
    
    def _get_mock_weather(self):
        """生成模拟天气数据"""
        # 模拟一些合理的天气情况
        weather_conditions = [
            {"description": "晴朗", "icon": "01d", "is_raining": False},
            {"description": "多云", "icon": "02d", "is_raining": False},
            {"description": "阴天", "icon": "04d", "is_raining": False},
            {"description": "小雨", "icon": "10d", "is_raining": True},
        ]
        
        condition = random.choice(weather_conditions)
        
        # 根据天气状况调整温度范围
        if condition["description"] == "晴朗":
            temp = round(random.uniform(15, 28), 1)
        elif condition["description"] == "多云":
            temp = round(random.uniform(12, 25), 1)
        elif condition["description"] == "阴天":
            temp = round(random.uniform(10, 22), 1)
        else:  # 雨天
            temp = round(random.uniform(8, 20), 1)
        
        return {
            'temperature': temp,
            'feels_like': round(temp + random.uniform(-1, 1), 1),
            'humidity': random.randint(40, 85),
            'wind_speed': round(random.uniform(1, 8), 1),
            'weather': condition["description"],
            'weather_icon': condition["icon"],
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'rain': random.uniform(0, 5) if condition["is_raining"] else 0,
            'is_raining': condition["is_raining"]
        }
    
    def _get_mock_forecast(self, days):
        """生成模拟天气预报数据"""
        forecasts = []
        base_date = datetime.now()
        
        for i in range(days):
            forecast_date = (base_date.replace(hour=12, minute=0, second=0) 
                           .fromordinal(base_date.toordinal() + i))
            
            # 随机生成天气数据
            weather_conditions = ["晴朗", "多云", "阴天", "小雨", "中雨"]
            condition = random.choice(weather_conditions)
            
            # 根据天气状况调整温度
            if condition in ["晴朗", "多云"]:
                temp = round(random.uniform(15, 28), 1)
                rain_prob = random.randint(0, 20)
            else:
                temp = round(random.uniform(8, 22), 1)
                rain_prob = random.randint(30, 80)
            
            forecast = {
                'date': forecast_date.strftime('%Y-%m-%d'),
                'temperature': temp,
                'weather': condition,
                'humidity': random.randint(40, 85),
                'wind_speed': round(random.uniform(1, 8), 1),
                'rain_prob': rain_prob
            }
            forecasts.append(forecast)
        
        return forecasts
    
    def evaluate_running_suitability(self, weather_data=None):
        """评估当前天气是否适合跑步"""
        if weather_data is None:
            weather_data = self.get_current_weather()
        
        # 检查各项指标
        temp_suitable = (self.optimal_temp_range[0] <= 
                        weather_data['temperature'] <= 
                        self.optimal_temp_range[1])
        
        wind_suitable = weather_data['wind_speed'] <= self.max_wind_speed
        rain_suitable = not weather_data['is_raining']
        humidity_suitable = weather_data['humidity'] <= self.max_humidity
        
        # 综合评分（0-100分）
        score = 100
        
        if not temp_suitable:
            # 温度不合适，扣20-40分
            temp_diff = max(abs(weather_data['temperature'] - self.optimal_temp_range[0]),
                          abs(weather_data['temperature'] - self.optimal_temp_range[1]))
            score -= min(40, temp_diff * 5)
        
        if not wind_suitable:
            # 风太大，扣20分
            score -= 20
        
        if not rain_suitable:
            # 正在下雨，扣30分
            score -= 30
        
        if not humidity_suitable:
            # 湿度太大，扣10分
            score -= 10
        
        # 确保分数在0-100之间
        score = max(0, min(100, score))
        
        # 生成建议
        if score >= 80:
            advice = "天气非常适合跑步，快去运动吧！"
        elif score >= 60:
            advice = "天气条件不错，可以进行跑步活动。"
        elif score >= 40:
            advice = "天气一般，建议适当调整运动强度。"
        elif score >= 20:
            advice = "天气不太适合跑步，考虑室内运动。"
        else:
            advice = "天气条件较差，不建议户外跑步。"
        
        return {
            'score': int(score),
            'advice': advice,
            'details': {
                'temperature': {
                    'value': weather_data['temperature'],
                    'suitable': temp_suitable,
                    'message': f"当前温度{weather_data['temperature']}°C，" 
                              f"{'适合' if temp_suitable else '不太适合'}跑步"
                },
                'wind': {
                    'value': weather_data['wind_speed'],
                    'suitable': wind_suitable,
                    'message': f"当前风速{weather_data['wind_speed']}m/s，" 
                              f"{'风力适宜' if wind_suitable else '风力较大'}"
                },
                'rain': {
                    'suitable': rain_suitable,
                    'message': f"{'无雨' if rain_suitable else '正在下雨'}，" 
                              f"{'适合' if rain_suitable else '不适合'}跑步"
                },
                'humidity': {
                    'value': weather_data['humidity'],
                    'suitable': humidity_suitable,
                    'message': f"当前湿度{weather_data['humidity']}%，" 
                              f"{'湿度适宜' if humidity_suitable else '湿度较大'}"
                }
            }
        }


if __name__ == "__main__":
    # 示例使用
    weather_api = WeatherAPI()
    
    # 获取当前天气
    current_weather = weather_api.get_current_weather()
    print("当前天气:")
    print(f"温度: {current_weather['temperature']}°C")
    print(f"天气状况: {current_weather['weather']}")
    print(f"湿度: {current_weather['humidity']}%")
    print(f"风速: {current_weather['wind_speed']}m/s")
    
    # 评估跑步适宜性
    suitability = weather_api.evaluate_running_suitability(current_weather)
    print("\n跑步适宜性评估:")
    print(f"得分: {suitability['score']}/100")
    print(f"建议: {suitability['advice']}")
    
    # 输出详细评估
    print("\n详细评估:")
    for key, item in suitability['details'].items():
        print(f"{item['message']}")